package parte2;

import java.util.Date;
import java.io.Serializable;
import java.sql.Time;
import java.util.List;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * Classe de um Evento
 * 
 * @author Samuel Wesley, Wellington Araújo e Gervásio Costa
 * 
 */
public class Evento implements Serializable {
	private static final long serialVersionUID = 1L;
	private String nome, descricao, tipo;
	private Time duracao;
	private Calendar dataInicio, dataFinal;
	private List<Contato> contatosNoEvento = new ArrayList<Contato>();
	private List<Anotacao> anotacoesDoEvento= new ArrayList<Anotacao>();

	/**
	 * Construtor de um Evento
	 * 
	 * @param nome
	 *            Nome do evento a ser criado
	 * @param dia
	 *            O dia do mês em que o Evento vai acontecer
	 * @param mes
	 *            O mês em que o Evento vai acontecer
	 * @param ano
	 *            O ano em que o Evento vai acontecer
	 * @param hora
	 *            A hora em que o Evento vai acontecer
	 * @param minuto
	 *            Os minutos em que o Evento vai acontecer
	 * @param duracao
	 *            String que representa a duração do evento. De formato
	 *            (HH:MM:SS)
	 * @param descricao
	 *            String com detalhes sobre o evento
	 * @param tipo
	 *            String que representa o tipo do Evento
	 */
	public Evento(String nome, int dia, int mes, int ano, int hora, int minuto,
			String duracao, String descricao, String tipo) {
		this.duracao = Time.valueOf(duracao);
		this.nome = nome;
		this.dataInicio = new GregorianCalendar(ano, mes - 1, dia, hora, minuto);
		determinaDataFinal(dataInicio, this.duracao);
		this.descricao = descricao;
		this.tipo = tipo;
	}

	/**
	 * Método que retorna o nome do Evento
	 * 
	 * @return String com o nome do Evento
	 */
	public String getNome() {
		return nome;
	}

	/**
	 * Método que modifica o nome do Evento para o passado como parâmetro
	 * 
	 * @param nome
	 *            String com o nome para o qual se deseja mudar o nome do Evento
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}

	/**
	 * Método que retorna o a data inicial do Evento
	 * 
	 * @return Objeto do tipo Calendar com a data inicial do Evento
	 */
	public Calendar getDataInicial() {
		return dataInicio;
	}

	/**
	 * Método que modifica a data inicial do Evento
	 * 
	 * @param dia
	 *            Dia do mês da nova data para a qual se deseja mudar a data do
	 *            Evento
	 * @param mes
	 *            Mês da nova data para a qual se deseja mudar a data do Evento
	 * @param ano
	 *            Ano da nova data para a qual se deseja mudar a data do Evento
	 * @param hora
	 *            Hora da nova data para a qual se deseja mudar a data do Evento
	 * @param minuto
	 *            Minutos da nova data para a qual se deseja mudar a data do
	 *            Evento
	 */
	public void setData(int dia, int mes, int ano, int hora, int minuto) {
		Calendar data = new GregorianCalendar(ano, mes - 1, dia, hora, minuto);
		this.dataInicio = data;
		determinaDataFinal(dataInicio, duracao);
	}

	/**
	 * Método que retorna a duração do Evento
	 * 
	 * @return Objeto do tipo Date com a duração do Evento
	 */
	public Date getDuracao() {
		return duracao;
	}

	/**
	 * Método que modifica a duração do Evento
	 * 
	 * @param duracao
	 *            String de formato "HH:MM:SS" com a duração do Evento para o
	 *            qual se deseja mudar.
	 */
	public void setDuracao(String duracao) {
		this.duracao = Time.valueOf(duracao);
		determinaDataFinal(dataInicio, this.duracao);

	}

	/**
	 * Método que retorna a descrição do Evento
	 * 
	 * @return String com a descrição do Evento
	 */
	public String getDescricao() {
		return descricao;
	}

	/**
	 * Método que modifica a descrição do Evento
	 * 
	 * @param descricao
	 *            String com a nova descrição para a qual se deseja mudar a
	 *            descrição do Evento
	 */
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	/**
	 * Método que retorna o tipo do Evento
	 * 
	 * @return String com o tipo do Evento
	 */
	public String getTipo() {
		return tipo;
	}

	/**
	 * Método que modifica o tipo do Evento
	 * 
	 * @param tipo
	 *            String com o novo tipo para o qual se deseja mudar o tipo do
	 *            Evento
	 */
	public void setTipo(String tipo) {
		this.tipo = tipo;
	}

	/**
	 * Método que retorna os contatos relacionados ao Evento
	 * 
	 * @return List com objetos do tipo Contato que estão relacionado com o
	 *         Evento
	 */
	public List<Contato> getContatosNoEvento() {
		return contatosNoEvento;
	}
	
	/**
	 * Método que retorna as anotacoes adicionadas ao Evento
	 * 
	 * @return List com objetos do tipo Anotacao que estão relacionados com o
	 *         Evento
	 */
	public List<Anotacao> getAnotacoes() {
		return anotacoesDoEvento;
	}

	/**
	 * Método que relaciona um novo Contato ao Evento, adicionando-o em uma
	 * lista com todos os Contatos relacionado ao Evento
	 * 
	 * @param contato
	 *            Contato que se deseja relacionar ao Evento
	 * @return true se o Contato for adicionado aos contatos do Evento e false
	 *         se o Contato não pôde ser adicionado corretamente.
	 */
	public boolean addContato(Contato contato) {
		if (!contatosNoEvento.contains(contato))
			return contatosNoEvento.add(contato);
		return false;
	}

	public boolean removeContato(Contato contato) {
		return contatosNoEvento.remove(contato);
	}

	/**
	 * Método que retorna a data final do Evento, calculada com base na data
	 * inicial e na duração do Evento
	 * 
	 * @return Objeto do tipo Calendar com a data final do Evento
	 */
	public Calendar getDataFinal() {
		return dataFinal;
	}

	@Override
	public String toString() {
		return nome + "\nTipo: " + tipo + "\nDescrição: " + descricao
				+ "\nInício: " + dataInicio.getTime() + "\nFinal: "
				+ dataFinal.getTime();
	}

	private void determinaDataFinal(Calendar dataInicio, Time duracao) {
		final Time ERRO = Time.valueOf("00:00:00");
		Calendar dataFinal = (Calendar) dataInicio.clone();
		dataFinal.setTimeInMillis(dataFinal.getTimeInMillis()
				+ duracao.getTime() - ERRO.getTime());
		this.dataFinal = dataFinal;
	}

}
